﻿/*************************************************************************
* 计算机名：AA-FA-05
* CLR 版本：4.0.30319.42000
* 命名空间: Unity
* 类    名：ObservableObject
* 当 前 域：HYRC
* 创 建 人：dailuyu
* 创建时间：2021/6/11 16:55:29
* 描    述：
*  V0.01 2021 初版
*
*  Copyright (c) 2021 aatsr Corporation. All rights reserved.
*  ┌──────────────────────────────────┐
*  │　此技术信息为本公司机密信息，未经本公司书面同意禁止向第三方披露．　│
*  └──────────────────────────────────┘
***************************************************************************/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using ValidationUnity;

namespace Unity
{
    public abstract class ObservableObject : ValidationUtility, INotifyPropertyChanged
    {
        [field: NonSerialized]
        public event PropertyChangedEventHandler PropertyChanged;

        private string error;

        protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            var handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpresssion)
        {
            var propertyName = PropertySupport.ExtractPropertyName(propertyExpresssion);
            this.RaisePropertyChanged(propertyName);
        }

        protected void RaisePropertyChanged(String propertyName)
        {
            VerifyPropertyName(propertyName);
            OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
        }

        /// <summary>
        /// Warns the developer if this Object does not have a public property with
        /// the specified name. This method does not exist in a Release build.
        /// </summary>
        [Conditional("DEBUG")]
        [DebuggerStepThrough]
        public void VerifyPropertyName(String propertyName)
        {
            // verify that the property name matches a real,  
            // public, instance property on this Object.
            if (TypeDescriptor.GetProperties(this)[propertyName] == null)
            {
                Debug.Fail("Invalid property name: " + propertyName);
            }
        }

        public bool IsValidated()
        {
            // 通过反射获取所有带自定义特性的属性，判断属性值是否满足要求
            var properties = GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (var property in properties)
            {
                // 属性Error和Item来自接口IDataErrorInfo，无需进行验证
                if (property.Name == "Error" || property.Name == "Item")
                {
                    continue;
                }
                var value = property.GetValue(this, null);
                var attributes = property.GetCustomAttributes(false);
                foreach (var attribute in attributes)
                {
                    if (attribute is NumberRuleAttribute numberRule)
                    {
                        if (!numberRule.IsValid(value))
                        {
                            error = numberRule.ErrorMessage;
                            return false;
                        }
                    }
                    else if (attribute is StringRuleAttribute stringRule)
                    {
                        if (!stringRule.IsValid(value))
                        {
                            error = stringRule.ErrorMessage;
                            return false;
                        }
                    }
                }
            }
            return true;
        }
    }
}
